﻿/// <reference path = "Base.ts" />
namespace VantCellTypes {
    interface ICascaderCellTypeParam extends IInputBaseParam {
        useBinding: boolean;
        options: any;
        bindingOptions: any;
        CascaderConfig: ICascaderConfig;
    }
    interface ICascaderConfig {
        title: string;
        activeColor: string;
        closeable: boolean;
        swipeable: boolean;
        showToolbar: boolean;
    }

    export class CascaderCellType extends InputBase<ICascaderCellTypeParam> {
        public setDataSource(dataSource) {
            return this.vue.setOptions(dataSource);
        }

        public onPageLoaded(info: Forguncy.Plugin.CellTypeInfo) {
            const self = this;
            const cellType = this.cellType;
            const config = cellType.CascaderConfig;
            let options = [];
            if (!cellType.useBinding && cellType.options) {
                options = cellType.options;
            }
            const input = this.getInputTemplate(`@click="onClick" clear-trigger="always" @clear="onClear"`);

            const optionStr = this.getCustomSlotByPath(SlotPath.cascaderOption);

            const option = {
                template: `
<div class="fgc-vant-inputContainer">
    ${input}
    <van-popup v-model:show="show" position="bottom" teleport="body">
      <van-cascader
        v-model="cascaderValue"
        :title="title"
        :options="options"
        :closeable="closeable"
        :show-header="showToolbar"
        :swipeable="swipeable"
        :activeColor="activeColor"
        @close="show = false"
        @finish="onFinish"
      >
        ${ optionStr ? "<template #option='data'>" + optionStr + "</template>" : "" }
      </van-cascader>
    </van-popup>
</div>`,
                data() {
                    const baseData = self.getData(cellType);
                    const data = {
                        show: false,
                        cellValue: undefined,
                        cascaderValue: undefined,
                        options: options,
                        title: config.title,
                        activeColor: Forguncy.ConvertToCssColor(config.activeColor),
                        closeable: !!config.closeable,
                        showToolbar: !!config.showToolbar,
                        swipeable: !!config.swipeable
                    };
                    return { ...baseData, ...data };
                },
                methods: this.getDefaultMethods({
                    onFinish({ selectedOptions }) {
                        this.show = false;
                        this.updataValueBySelectedOption(selectedOptions);
                        this.cellValue = this.cascaderValue;
                        self.commitValue();
                        self.validate();
                    },
                    onClick() {
                        if (!self.isReadOnly() && !self.isDisabled()) {
                            this.show = true;
                            this.cascaderValue = this.cellValue;
                        }
                    },
                    onClear() {
                        this.cellValue = null;
                        self.commitValue();
                        self.validate();
                    },
                    getValue() {
                        return this.cellValue;
                    },
                    setValue(value) {
                        if (this.cellValue !== value) {
                            this.cellValue = value;
                            this.updateValue();
                        }
                    },
                    updateValue() {
                        const selectedOptions = CascaderCellType.getPathByValue(this.options, this.cellValue);
                        this.updataValueBySelectedOption(selectedOptions);
                    },
                    updataValueBySelectedOption(selectedOptions) {
                        if (selectedOptions) {
                            this.value = selectedOptions.map((option) => option.text).join('/');
                        }
                        else {
                            this.value = null;
                        }
                    },
                    setOptions(options) {
                        if (options) {
                            TreeHelper.flat(options).forEach(i => {
                                if ((<any>i)?.text) {
                                    (<any>i).text = self.format((<any>i).text);
                                }
                            });
                            this.options = options;
                        } else {
                            this.options = [];
                        }
                    }
                }),
                mounted() {
                    self.setFontToInputDom(this);

                    $(".van-field__control", self.container).attr("readonly", "readonly");
                }
            };

            this.createVueApp(option);

            if (cellType.useBinding) {
                SupportDataSourceCellType.refreshData(this, cellType.bindingOptions, data => this.setDataSource(TreeHelper.build(data)));
            }
            super.onPageLoaded(info);
        }

        public static getPathByValue(options: ITreeNodeBase[], value: any, curretPath = []) {
            if (!options) {
                return null;
            }
            for (const option of options) {
                // eslint-disable-next-line
                if (option.value == value) {
                    return curretPath.concat([option]);
                }
                if (option.children) {
                    const result = this.getPathByValue(option.children, value, curretPath.concat([option]));
                    if (result) {
                        return result;
                    }
                }
            }
            return null;
        }

        public SetDataSourceByObjTree(dataSource: any[], valueProperty, labelProperty, childrenProperty) {
            if (typeof dataSource === "string") {
                dataSource = JSON.parse(dataSource);
            }
            if (childrenProperty) {
                childrenProperty = childrenProperty.split('|');
            }
            if (valueProperty) {
                valueProperty = valueProperty.split('|');
            }
            if (labelProperty) {
                labelProperty = labelProperty.split('|');
            }
            if (!labelProperty) {
                labelProperty = valueProperty;
            }

            const source = this.buildTree(dataSource, valueProperty, labelProperty, childrenProperty);
            this.setDataSource(source);
        }

        private buildTree(dataSource: any[], valueProperty: string[], labelProperty: string[], childrenProperty: string[]) {
            if (!dataSource) {
                return undefined;
            }
            return dataSource.map(i => <any>{
                value: this.getSubPropertyValue(i, valueProperty),
                text: this.getSubPropertyValue(i, labelProperty),
                children: this.buildTree(this.getSubPropertyValue(i, childrenProperty), valueProperty, labelProperty, childrenProperty),
            });
        }

        private getSubPropertyValue(obj, subProperties: string[]) {
            for (const prop of subProperties) {
                if (obj[prop] !== undefined) {
                    return obj[prop];
                }
            }
            return undefined;
        }

        public SetDataSourceByIdPidTable(dataSource: any[], valueProperty, labelProperty, parentValue) {
            if (typeof dataSource === "string") {
                dataSource = JSON.parse(dataSource);
            }
            const treeObj = TreeHelper.build(dataSource.map(i => <IItem>{
                value: i[valueProperty],
                text: i[labelProperty],
                parentValue: i[parentValue],
            }));
            this.setDataSource(treeObj);
        }

        public GetCheckedNodes(leafOnly) {
            if (typeof (leafOnly) === "string") {
                leafOnly = !(leafOnly.toLowerCase() === "false" || leafOnly.toLowerCase() === "0");
            }
            else {
                leafOnly = !!leafOnly;
            }
            return {
                CheckedItems: this.vue.$refs.elInput.getCheckedNodes(leafOnly).map(i => <any>{
                    "value": i.value,
                    "text": i.text,
                })
            };
        }

        public ShowPopup() {
            this.vue.onClick();
        }
    }
}

Forguncy.Plugin.CellTypeHelper.registerCellType("Vant.CellTypes.Cascader, Vant", VantCellTypes.CascaderCellType);